package nioServer;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.nio.ByteBuffer;
import java.nio.channels.SelectionKey;
import java.nio.channels.Selector;
import java.nio.channels.ServerSocketChannel;
import java.nio.channels.SocketChannel;
import java.util.Arrays;

public class NioServer {
    private int port;
    private Selector selector;

    public NioServer(int port) {
        this.port = port;
    }

    public void run() throws IOException {
        selector = Selector.open();
        ServerSocketChannel serverSocketChannel = ServerSocketChannel.open();
        serverSocketChannel.bind(new InetSocketAddress(port));
        //注册为非阻塞的管道
        serverSocketChannel.configureBlocking(false);
        serverSocketChannel.register(selector, SelectionKey.OP_ACCEPT);

        while (true) {
            if (selector.select() == 0) {
                //等待管道准备的同时 打印
//                System.out.println("hehehehda");
                continue;
            }
            selector.selectedKeys().forEach((selectionKey) -> {
                try {

                    switch (selectionKey.interestOps()) {
                        case SelectionKey.OP_ACCEPT:
                            System.out.println("准备连接");
                            SocketChannel socketChannel = serverSocketChannel.accept();
                            if (socketChannel != null) {
                                socketChannel.configureBlocking(false).register(selector, SelectionKey.OP_READ);
                            }
                            break;
                        case SelectionKey.OP_CONNECT:

                            break;
                        case SelectionKey.OP_READ:

                            SocketChannel channel = (SocketChannel) selectionKey.channel();
                            ByteBuffer buffer = ByteBuffer.allocate(1024);
                            StringBuilder stringBuffer = new StringBuilder();
                            byte[] bytes;
                            int size = 0;
                            ByteArrayOutputStream baos = new ByteArrayOutputStream();
                            long old = System.currentTimeMillis();
                            while ((size = channel.read(buffer)) > 0) {
                                bytes = new byte[size];
                                buffer.flip();
                                buffer.get(bytes);
                                baos.write(bytes);
                                buffer.clear();
                            }
                            String s = new String(baos.toByteArray());
                            System.out.println("接收到：" + new String(baos.toByteArray()));
                            baos.flush();
                            baos.close();
                            if (s.length() > 0) {
                                ByteBuffer buffer1 = ByteBuffer.allocate(1024);
                                StringBuilder resp = new StringBuilder();
                                resp.append("HTTP/1.1 200OJBK\r\n");
                                resp.append("ContentType: text/html;charset=UTF-8\r\n");
                                resp.append("\r\n");
                                resp.append("hello, 摸摸大!");
                                System.out.println(resp);
                                System.out.println("GBK:" + Arrays.toString(resp.toString().getBytes("GBK")));
                                System.out.println("默认：" + Arrays.toString(resp.toString().getBytes()));
                                buffer1.put(resp.toString().getBytes("GBK"));
                                buffer1.flip();
                                channel.write(buffer1);
                                channel.configureBlocking(false).register(selector, SelectionKey.OP_WRITE);
                            }
                            break;
                        case SelectionKey.OP_WRITE:
                            System.out.println("写出了");
                            SocketChannel channel1 = (SocketChannel) selectionKey.channel();
                            channel1.shutdownInput();
                            channel1.close();
                            break;
                    }

                } catch (IOException e) {
                    e.printStackTrace();
                }

            });
        }
    }
}
